package hu.mapro.model.meta;

import hu.mapro.model.impl.Cardinality;
import hu.mapro.model.meta.BuiltinType.BuiltinTypeCategory;
import hu.mapro.model.meta.Type.TypeCategory;

import java.util.Collection;
import java.util.List;

import com.google.common.collect.Lists;

public class MetaUtils {

	public static <T> Field<? super T, ?> findField(ComplexType<T> type, String fieldName) {
		for (Field<T, ?> f : type.getFields()) {
			if (f.getName().equals(fieldName)) {
				return f;
			}
		}

		if (type.getSuperType()!=null) {
			return findField(type.getSuperType(), fieldName);
		}
		
		return null;
	}
	
	public static <T> Collection<Field<? super T, ?>> getReadableFields(ComplexType<T> type) {
		List<Field<? super T, ?>> result = Lists.newArrayList();
		
		if (type.getSuperType()!=null) {
			result.addAll(getReadableFields(type.getSuperType()));
		}

		for (Field<T, ?> f : type.getFields()) {
			if (f.isReadable()) {
				result.add(f);
			}
		}
		
		return result;
	}

	public static <T>  Collection<Field<? super T, ?>> getReadWriteFields(ComplexType<T> type) {
		List<Field<? super T, ?>> result = Lists.newArrayList();
		
		if (type.getSuperType()!=null) {
			result.addAll(getReadWriteFields(type.getSuperType()));
		}
		
		for (Field<T, ?> f : type.getFields()) {
			if (f.isReadable() && f.isWritable()) {
				result.add(f);
			}
		}
		
		return result;
	}
	
	public static boolean isComplexType(DefinedType<?> bid) {
		return bid.getTypeCategory()==TypeCategory.ENTITY || bid.getTypeCategory()==TypeCategory.VALUE;
	}

	public static boolean isPluralField(Field<?, ?> pd) {
		return pd.getCardinality()==Cardinality.LIST || pd.getCardinality()==Cardinality.SET;
	}

	public static BuiltinTypeCategory getBuiltinType(String fullClassName) {
		for (BuiltinTypeCategory c : BuiltinTypeCategory.values()) {
			if (c.getTypeClass().getName().equals(fullClassName)) {
				return c;
			}
		}
		return null;
	}

	public static boolean isBuiltinType(String fullClassName) {
		return getBuiltinType(fullClassName)!=null;
	}
	
	
}
